package org.layuiframework.generator.engine;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.FileType;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.tomcat.util.codec.binary.Base64;
import org.layuiframework.generator.config.LayuiConfigBuilder;
import org.layuiframework.generator.config.LayuiGlobalConfig;
import org.layuiframework.generator.config.LayuiTemplateConfig;
import org.layuiframework.generator.config.es.EsStrategy;
import org.layuiframework.generator.config.po.LayuiTableInfo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <h2>
 *     重写Freemarker的模版渲染引擎
 * </h2>
 *
 * <i> 这里重写主要是想重写 {@linkplain AbstractTemplateEngine#getObjectMap 组装模版参数 } 可以在模版参数中新增一些渲染layui模版专用参数  </i>
 *
 * <p> 顺便可以通过debug研究逆向的渲染过程 </p>
 */
public class FreemarkerTemplateEngine extends AbstractTemplateEngine {

    private Configuration configuration;

    public static void main2(String[] args) {
//        String str = "1234(56789)";
//        final String N_PLUS_PATTREN = "^[^\\(|^\\)]+(\\(([^\\(|^\\)]+)\\))?$";
//        Pattern pattern = Pattern.compile(N_PLUS_PATTREN);
//        Matcher matcher = pattern.matcher(str);
//        String finalStr = matcher.find() ? matcher.group(matcher.groupCount()) : "";
//        System.out.println(finalStr);
//        System.out.println(matcher.groupCount());
//        System.out.println(matcher.group(0));
//        System.out.println(matcher.group(1));
//        System.out.println(matcher.group(2));

        String str = "radio:12.55.6";
        final String N_PLUS_PATTREN = "^radio:([^\\.|^;|^:]+\\.[^\\.|^;]+;?)+$";
        Pattern pattern = Pattern.compile(N_PLUS_PATTREN);
        Matcher matcher = pattern.matcher(str);
        System.out.println(matcher.find());
//        System.out.println(matcher.groupCount());
//        System.out.println(matcher.group(0));
//        System.out.println(matcher.group(1));
//        System.out.println(matcher.group(2));
    }

    public FreemarkerTemplateEngine init(ConfigBuilder configBuilder) {
        super.init(configBuilder);
        this.configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        this.configuration.setDefaultEncoding(ConstVal.UTF8);
        /**
         * 注意:
         * 这一步是去设置 Freemarker 模版文件 相对于当前这个java文件的位置。
         * 由于使用的不是默认的 模版引擎了，文件位置会发生改变
         */
        this.configuration.setClassForTemplateLoading(FreemarkerTemplateEngine.class, "/");
        return this;
    }

    @Override
    public void writer(Map<String, Object> objectMap, String templatePath, String outputFile) throws Exception {
        Template template = this.configuration.getTemplate(templatePath);
        /**
         * 这一步的文件在处理之前就已经生成了文件路径和文件
         */
        FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
        Throwable var6 = null;

        try {
            template.process(objectMap, new OutputStreamWriter(fileOutputStream, ConstVal.UTF8));
        } catch (Throwable var15) {
            var6 = var15;
            throw var15;
        } finally {
            if (fileOutputStream != null) {
                if (var6 != null) {
                    try {
                        fileOutputStream.close();
                    } catch (Throwable var14) {
                        var6.addSuppressed(var14);
                    }
                } else {
                    fileOutputStream.close();
                }
            }
        }
        logger.debug("模板:" + templatePath + ";  文件:" + outputFile);
    }

    @Override
    public String templateFilePath(String filePath) {
        return filePath + ".ftl";
    }

    /**
     * 获取模版解析的参数
     * @param tableInfo 预处理参数
     * @return 模版解析的参数
     */
    @Override
    public Map<String, Object> getObjectMap(TableInfo tableInfo) {
        ConfigBuilder config = this.getConfigBuilder();
        HashMap objectMap;
        if (config.getStrategyConfig().isControllerMappingHyphenStyle()) {
            objectMap = CollectionUtils.newHashMapWithExpectedSize(33);
            objectMap.put("controllerMappingHyphenStyle", config.getStrategyConfig().isControllerMappingHyphenStyle());
            objectMap.put("controllerMappingHyphen", StringUtils.camelToHyphen(tableInfo.getEntityPath()));
        } else {
            objectMap = CollectionUtils.newHashMapWithExpectedSize(31);
        }
        objectMap.put("restControllerStyle", config.getStrategyConfig().isRestControllerStyle());
        objectMap.put("config", config);
        objectMap.put("package", config.getPackageInfo());
        GlobalConfig globalConfig = config.getGlobalConfig();
        objectMap.put("author", globalConfig.getAuthor());
        objectMap.put("idType", globalConfig.getIdType() == null ? null : globalConfig.getIdType().toString());
        objectMap.put("logicDeleteFieldName", config.getStrategyConfig().getLogicDeleteFieldName());
        objectMap.put("versionFieldName", config.getStrategyConfig().getVersionFieldName());
        objectMap.put("activeRecord", globalConfig.isActiveRecord());
        objectMap.put("kotlin", globalConfig.isKotlin());
        objectMap.put("swagger2", globalConfig.isSwagger2());
        objectMap.put("date", (new SimpleDateFormat("yyyy-MM-dd")).format(new Date()));
        // objectMap.put("table", tableInfo);
        // 保存表格信息
        LayuiTableInfo layuiTableInfo = new LayuiTableInfo(tableInfo);
        LayuiTableInfoLoader.get().put(tableInfo.getName(), layuiTableInfo);
        objectMap.put("table", layuiTableInfo);
        LayuiConfigBuilder builder = LayuiConfigBuilder.class.cast(config);
        objectMap.put("dataSourceUsername", builder.getDataSourceConfig().getUsername());
        objectMap.put("dataSourcePassword", builder.getDataSourceConfig().getPassword());
        objectMap.put("dataSourceUrl", builder.getDataSourceConfig().getUrl());
        objectMap.put("dataSourceDrivername", builder.getDataSourceConfig().getDriverName());
        objectMap.put("fullComment", LayuiGlobalConfig.FUUL_COMMENT);

        // 设置 Elasticsearch 参数
        objectMap.put("ES_URIS", LayuiGlobalConfig.ES_URIS);
        objectMap.put("ES_USERNAME", LayuiGlobalConfig.ES_USERNAME);
        objectMap.put("ES_PASSWORD", LayuiGlobalConfig.ES_PASSWORD);
        // 保存es同步策略类型
        objectMap.put("ES_STRATEGY", LayuiGlobalConfig.ES_STRATEGY);
        objectMap.put("ES_STRATEGY_TASK", EsStrategy.SCHEDULED_TASK.getStrategy());
        objectMap.put("ES_STRATEGY_DOUBLE_WRITE", EsStrategy.DOUBLE_WRITE.getStrategy());
        objectMap.put("ES_STRATEGY_LOGSTASH", EsStrategy.LOGSTASH_PIPES.getStrategy());
        objectMap.put("ES_STRATEGY_DEFAULT", EsStrategy.CANAL.getStrategy());

        objectMap.put("enableCache", globalConfig.isEnableCache());
        objectMap.put("baseResultMap", globalConfig.isBaseResultMap());
        objectMap.put("baseColumnList", globalConfig.isBaseColumnList());
        objectMap.put("entity", tableInfo.getEntityName());
        objectMap.put("entitySerialVersionUID", config.getStrategyConfig().isEntitySerialVersionUID());
        objectMap.put("entityColumnConstant", config.getStrategyConfig().isEntityColumnConstant());
        objectMap.put("entityBuilderModel", config.getStrategyConfig().isEntityBuilderModel());
        objectMap.put("chainModel", config.getStrategyConfig().isChainModel());
        objectMap.put("entityLombokModel", config.getStrategyConfig().isEntityLombokModel());
//        objectMap.put("entityLombokModel", false);
        objectMap.put("entityBooleanColumnRemoveIsPrefix", config.getStrategyConfig().isEntityBooleanColumnRemoveIsPrefix());
        objectMap.put("superEntityClass", this.getSuperClassName(config.getStrategyConfig().getSuperEntityClass()));
        objectMap.put("superMapperClassPackage", config.getStrategyConfig().getSuperMapperClass());
        objectMap.put("superMapperClass", this.getSuperClassName(config.getStrategyConfig().getSuperMapperClass()));
        objectMap.put("superServiceClassPackage", config.getStrategyConfig().getSuperServiceClass());
        objectMap.put("superServiceClass", this.getSuperClassName(config.getStrategyConfig().getSuperServiceClass()));
        objectMap.put("superServiceImplClassPackage", config.getStrategyConfig().getSuperServiceImplClass());
        objectMap.put("superServiceImplClass", this.getSuperClassName(config.getStrategyConfig().getSuperServiceImplClass()));
        objectMap.put("superControllerClassPackage", this.verifyClassPacket(config.getStrategyConfig().getSuperControllerClass()));
        objectMap.put("superControllerClass", this.getSuperClassName(config.getStrategyConfig().getSuperControllerClass()));
        return (Map)(Objects.isNull(config.getInjectionConfig()) ? objectMap : config.getInjectionConfig().prepareObjectMap(objectMap));
    }

    private String getSuperClassName(String classPath) {
        return StringUtils.isBlank(classPath) ? null : classPath.substring(classPath.lastIndexOf(".") + 1);
    }

    private String verifyClassPacket(String classPacket) {
        return StringUtils.isBlank(classPacket) ? null : classPacket;
    }


//    @Override
    public AbstractTemplateEngine batchOutput(String msg) {
        try {
            List<TableInfo> tableInfoList = this.getConfigBuilder().getTableInfoList();
            Iterator var2 = tableInfoList.iterator();

            while(var2.hasNext()) {
                TableInfo tableInfo = (TableInfo)var2.next();
                Map<String, Object> objectMap = this.getObjectMap(tableInfo);
                TemplateConfig template = this.getConfigBuilder().getTemplate();
                template.getController();
            }
        } catch (Exception var11) {
            logger.error("无法创建文件，请检查配置信息！", var11);
        }
        return this;
    }

    @Override
    public AbstractTemplateEngine batchOutput() {
        try {
            List<TableInfo> tableInfoList = this.getConfigBuilder().getTableInfoList();
            Iterator var2 = tableInfoList.iterator();

            while(var2.hasNext()) {
                TableInfo tableInfo = (TableInfo)var2.next();
                Map<String, Object> objectMap = this.getObjectMap(tableInfo);
                Map<String, String> pathInfo = this.getConfigBuilder().getPathInfo();
                TemplateConfig template = this.getConfigBuilder().getTemplate();
                InjectionConfig injectionConfig = this.getConfigBuilder().getInjectionConfig();
                if (null != injectionConfig) {
                    injectionConfig.initTableMap(tableInfo);
                    objectMap.put("cfg", injectionConfig.getMap());
                    List<FileOutConfig> focList = injectionConfig.getFileOutConfigList();
                    if (CollectionUtils.isNotEmpty(focList)) {
                        Iterator var9 = focList.iterator();

                        while(var9.hasNext()) {
                            FileOutConfig foc = (FileOutConfig)var9.next();
                            if (this.isCreate(FileType.OTHER, foc.outputFile(tableInfo))) {
                                this.writerFile(objectMap, foc.getTemplatePath(), foc.outputFile(tableInfo));
                            }
                        }
                    }
                }

                String entityName = tableInfo.getEntityName();
                String controllerFile;
                if (null != entityName && null != pathInfo.get("entity_path")) {
                    controllerFile = String.format((String)pathInfo.get("entity_path") + File.separator + "%s" + this.suffixJavaOrKt(), entityName);
                    if (this.isCreate(FileType.ENTITY, controllerFile)) {
                        this.writerFile(objectMap, this.templateFilePath(template.getEntity(this.getConfigBuilder().getGlobalConfig().isKotlin())), controllerFile);
                    }
                }

                if (null != tableInfo.getMapperName() && null != pathInfo.get("mapper_path")) {
                    controllerFile = String.format((String)pathInfo.get("mapper_path") + File.separator + tableInfo.getMapperName() + this.suffixJavaOrKt(), entityName);
                    if (this.isCreate(FileType.MAPPER, controllerFile)) {
                        this.writerFile(objectMap, this.templateFilePath(template.getMapper()), controllerFile);
                    }
                }

                if (null != tableInfo.getXmlName() && null != pathInfo.get("xml_path")) {
                    controllerFile = String.format((String)pathInfo.get("xml_path") + File.separator + tableInfo.getXmlName() + ".xml", entityName);
                    if (this.isCreate(FileType.XML, controllerFile)) {
                        this.writerFile(objectMap, this.templateFilePath(template.getXml()), controllerFile);
                    }
                }

                if (null != tableInfo.getServiceName() && null != pathInfo.get("service_path")) {
                    controllerFile = String.format((String)pathInfo.get("service_path") + File.separator + tableInfo.getServiceName() + this.suffixJavaOrKt(), entityName);
                    if (this.isCreate(FileType.SERVICE, controllerFile)) {
                        this.writerFile(objectMap, this.templateFilePath(template.getService()), controllerFile);
                    }
                }

                if (null != tableInfo.getServiceImplName() && null != pathInfo.get("service_impl_path")) {
                    controllerFile = String.format((String)pathInfo.get("service_impl_path") + File.separator + tableInfo.getServiceImplName() + this.suffixJavaOrKt(), entityName);
                    if (this.isCreate(FileType.SERVICE_IMPL, controllerFile)) {
                        this.writerFile(objectMap, this.templateFilePath(template.getServiceImpl()), controllerFile);
                    }
                }

                if (null != tableInfo.getControllerName() && null != pathInfo.get("controller_path")) {
                    controllerFile = String.format((String)pathInfo.get("controller_path") + File.separator + tableInfo.getControllerName() + this.suffixJavaOrKt(), entityName);
                    if (this.isCreate(FileType.CONTROLLER, controllerFile)) {
                        this.writerFile(objectMap, this.templateFilePath(template.getController()), controllerFile);
                    }
                }

                LayuiTableInfo layuiTableInfo = (LayuiTableInfo)objectMap.get("table");
                LayuiTemplateConfig layuiTemplate = LayuiTemplateConfig.class.cast(template);

                // 输出vo
                String voPath = String.format((String)pathInfo.get("vo_path") + File.separator + layuiTableInfo.getVoName()+ this.suffixJavaOrKt(), entityName);
                if (this.isCreate(FileType.OTHER, voPath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_vo()), voPath);
                }

                // 输出advice, 这个后面阔以放到外面去
                String advicePath = String.format((String)pathInfo.get("advice_path") + File.separator + layuiTableInfo.getAdviceName()+ this.suffixJavaOrKt(), entityName);
                if (this.isCreate(FileType.OTHER, advicePath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_advice()), advicePath);
                }

                advicePath = String.format((String)pathInfo.get("advice_path") + File.separator + "DataSourceConfig"+ this.suffixJavaOrKt(), entityName);
                if (this.isCreate(FileType.OTHER, advicePath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_datasource()), advicePath);
                }

                // spring 配置
                String springConfigPath = System.getProperty("user.dir") + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "application.yml";
                if (this.isCreate(FileType.OTHER, springConfigPath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_config_yml()), springConfigPath);
                }

                // 输出首页html、js
                String indexHtmlPath = System.getProperty("user.dir") + File.separator + "web" + File.separator + "index.html";
                String indexJsPath = System.getProperty("user.dir") + File.separator + "web" + File.separator + "index.js";
                if (this.isCreate(FileType.OTHER, indexHtmlPath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_index_html()), indexHtmlPath);
                }
                if (this.isCreate(FileType.OTHER, indexJsPath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_index_js()), indexJsPath);
                }

                // 输出html
                String htmlPath = String.format((String)pathInfo.get("html_path") + File.separator + layuiTableInfo.getMessageHtmlName()+ this.suffixHtml(), entityName);
                if (this.isCreate(FileType.OTHER, htmlPath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_html()), htmlPath);
                }
                // add
                htmlPath = String.format((String)pathInfo.get("html_path") + File.separator + layuiTableInfo.getMessageHtmlName() + "Add" + this.suffixHtml(), entityName);
                if (this.isCreate(FileType.OTHER, htmlPath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_add_html()), htmlPath);
                }

                // update
                htmlPath = String.format((String)pathInfo.get("html_path") + File.separator + layuiTableInfo.getMessageHtmlName() + "Update" + this.suffixHtml(), entityName);
                if (this.isCreate(FileType.OTHER, htmlPath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_update_html()), htmlPath);
                }

                // 输出js
                String jsPath = String.format((String)pathInfo.get("js_path") + File.separator + layuiTableInfo.getMessageHtmlName()+ this.suffixJs(), entityName);
                if (this.isCreate(FileType.OTHER, jsPath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_js()), jsPath);
                }

                // add
                jsPath = String.format((String)pathInfo.get("js_path") + File.separator + layuiTableInfo.getMessageHtmlName() + "Add" + this.suffixJs(), entityName);
                if (this.isCreate(FileType.OTHER, jsPath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_add_js()), jsPath);
                }

                // update
                jsPath = String.format((String)pathInfo.get("js_path") + File.separator + layuiTableInfo.getMessageHtmlName() + "Update" + this.suffixJs(), entityName);
                if (this.isCreate(FileType.OTHER, jsPath)) {
                    this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_update_js()), jsPath);
                }

                // elasticsearch
                if(org.springframework.util.StringUtils.hasLength(LayuiGlobalConfig.ES_URIS)){
                    controllerFile = String.format((String)pathInfo.get("entity_path") + File.separator + "%s" + "Es" + this.suffixJavaOrKt(), entityName);
                    if (this.isCreate(FileType.ENTITY, controllerFile)) {
                        this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_elasticsearch_entry()), controllerFile);
                    }
                    controllerFile = String.format((String)pathInfo.get("dao_path") + File.separator + "%s" + "EsDao" + this.suffixJavaOrKt(), entityName);
                    if (this.isCreate(FileType.ENTITY, controllerFile)) {
                        this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_elasticsearch_dao()), controllerFile);
                    }
                    controllerFile = String.format((String)pathInfo.get("es_path") + File.separator + "%s" + "ElasticsearchHandler" + this.suffixJavaOrKt(), entityName);
                    if (this.isCreate(FileType.ENTITY, controllerFile)) {
                        this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_elasticsearch_handler()), controllerFile);
                    }
                    // 采用定时任务同步策略
                    if(objectMap.get("ES_STRATEGY").equals(objectMap.get("ES_STRATEGY_TASK"))){
                        controllerFile = String.format((String)pathInfo.get("task_path") + File.separator + "once" + File.separator +"FullSync%sToEs" + this.suffixJavaOrKt(), entityName);
                        if (this.isCreate(FileType.OTHER, controllerFile)) {
                            this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_elasticsearch_fulltask()), controllerFile);
                        }
                        controllerFile = String.format((String)pathInfo.get("task_path") + File.separator + "cycle" + File.separator +"IncrSync%sToEs" + this.suffixJavaOrKt(), entityName);
                        if (this.isCreate(FileType.OTHER, controllerFile)) {
                            this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_elasticsearch_incrtask()), controllerFile);
                        }
                    }
                    // 采用logstash定时任务同步策略
                    if(objectMap.get("ES_STRATEGY").equals(objectMap.get("ES_STRATEGY_LOGSTASH")) && layuiTableInfo.getUpdateColumn() != null ){
                        controllerFile = String.format((String)pathInfo.get("task_path") + File.separator + "once" + File.separator +"FullSync%sToEs" + this.suffixJavaOrKt(), entityName);
                        if (this.isCreate(FileType.OTHER, controllerFile)) {
                            this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_elasticsearch_fulltask()), controllerFile);
                        }
                        String logstashConfigPath = System.getProperty("user.dir") + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "logstash" + File.separator + layuiTableInfo.getLayuiEntityName() + "task.conf";
                        String driversPath = getDriversPath(objectMap.get("dataSourceDrivername").toString());
                        objectMap.put("driversPath", driversPath);
                        if (this.isCreate(FileType.OTHER, logstashConfigPath)) {
                            this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_logstash_config()), logstashConfigPath);
                        }
                    }
                }
            }
        } catch (Exception var11) {
            logger.error("无法创建文件，请检查配置信息！", var11);
        }

        return this;
    }

    public String getDriversPath(String driversName){
        try{
            Class targetclass = Class.forName(driversName);
            String className = targetclass.getName();
            className = className.replace('.', '/');
            String resource = "/" + className + ".class";
            URL url = targetclass.getResource(resource);
            String path = url.getFile().split("!")[0].replace("/", File.separator).replace("file:" + File.separator, "");
            return path;
        }catch (Exception e){
            return "";
        }
    }

    public boolean isCreate(FileType fileType, String filePath) {
        return super.isCreate(fileType, filePath);
    }

    public void writerFile(Map<String, Object> objectMap, String templatePath, String outputFile) throws Exception {
        super.writerFile(objectMap, templatePath, outputFile);
    }

    public void open() {
        String outDir = this.getConfigBuilder().getGlobalConfig().getOutputDir();
        if (this.getConfigBuilder().getGlobalConfig().isOpen() && StringUtils.isNotBlank(outDir)) {
            try {
                String osName = System.getProperty("os.name");
                if (osName != null) {
                    if (osName.contains("Mac")) {
                        Runtime.getRuntime().exec("open " + outDir);
                    } else if (osName.contains("Windows")) {
                        Runtime.getRuntime().exec("cmd /c start " + outDir);
                    } else {
                        logger.debug("文件输出目录:" + outDir);
                    }
                }
            } catch (IOException var3) {
                var3.printStackTrace();
            }
        }
        // 输出配置js文件
        String jsPath = System.getProperty("user.dir") + File.separator + "web" + File.separator + "config.js";
        LayuiTemplateConfig layuiTemplate = LayuiTemplateConfig.class.cast(this.getConfigBuilder().getTemplate());
        HashMap objectMap = new HashMap();
        objectMap.put("ES_URIS", LayuiGlobalConfig.ES_URIS);
        objectMap.put("fields", LayuiTableInfoLoader.get().values().stream().collect(Collectors.toList()));
        objectMap.put("author", this.getConfigBuilder().getGlobalConfig().getAuthor());
        objectMap.put("date", (new SimpleDateFormat("yyyy-MM-dd")).format(new Date()));
        objectMap.put("fullComment", LayuiGlobalConfig.FUUL_COMMENT);
        ConfigBuilder config = this.getConfigBuilder();
        objectMap.put("package", config.getPackageInfo());
        Map<String, String> pathInfo = this.getConfigBuilder().getPathInfo();

        String voPath = (String)pathInfo.get("stereotype_path");
        // 输出stereotype文件
        StereotypePath.generator(voPath,objectMap, this);

        // 输出验证码控制器
        String controllerPath = String.format((String)pathInfo.get("controller_path") + File.separator + "IndexController" + this.suffixJavaOrKt(), "");
        try {
            if(this.isCreate(FileType.CONTROLLER, controllerPath)){
                this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_security_controller()), controllerPath);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 输出springsecurity相关
        String userPath = String.format((String)pathInfo.get("security_path") + File.separator + "WebUser" + this.suffixJavaOrKt(), "");
        try {
            if(this.isCreate(FileType.OTHER, userPath)){
                this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_security_webuser()), userPath);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        String configPath = String.format((String)pathInfo.get("security_path") + File.separator + "WebSecurityConfig" + this.suffixJavaOrKt(), "");
        try {
            if(this.isCreate(FileType.OTHER, configPath)){
                this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_security_config()), configPath);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        String keypairPath = String.format((String)pathInfo.get("security_path") + File.separator + "KeyPair" + this.suffixJavaOrKt(), "");
        try {
            if(!org.springframework.util.StringUtils.hasLength(LayuiGlobalConfig.LAYUI_PUBLIC_KEY) || !org.springframework.util.StringUtils.hasLength(LayuiGlobalConfig.LAYUI_PRIVATE_KEY)){
                // 生成RSA密钥
                KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
                keyPairGen.initialize(1024,new SecureRandom());
                KeyPair keyPair = keyPairGen.generateKeyPair();
                RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
                RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
                LayuiGlobalConfig.LAYUI_PUBLIC_KEY = new String( Base64.encodeBase64(publicKey.getEncoded()));
                LayuiGlobalConfig.LAYUI_PRIVATE_KEY = new String( Base64.encodeBase64((privateKey.getEncoded())));
            }
            objectMap.put("publicKey", LayuiGlobalConfig.LAYUI_PUBLIC_KEY);
            objectMap.put("privateKey", LayuiGlobalConfig.LAYUI_PRIVATE_KEY);
            objectMap.put("layuiUserField", LayuiGlobalConfig.LAYUI_USER_FIELD);
            this.isCreate(FileType.OTHER, keypairPath);
            this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getSpring_security_keypair()), keypairPath);
            // 放在下面，顺便输入公钥
            this.isCreate(FileType.OTHER, jsPath);
            this.writerFile(objectMap, this.templateFilePath(layuiTemplate.getLayui_config_js()), jsPath);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    protected String suffixHtml() {
        return ".html" ;
    }

    protected String suffixJs() {
        return ".js" ;
    }

}
